Skip to content

fix(debuglog): don't crash run when archiving debug logs (#1522)#3329

Open
fantasyRqg wants to merge 1 commit into
mobile-dev-inc:mainfrom
fantasyRqg:fix/1522-debuglog-archival-crash
Open

fix(debuglog): don't crash run when archiving debug logs (#1522)#3329
fantasyRqg wants to merge 1 commit into
mobile-dev-inc:mainfrom
fantasyRqg:fix/1522-debuglog-archival-crash

Conversation

@fantasyRqg

Copy link
Copy Markdown

Proposed changes

Fixes a crash where a successful run could fail at the very end with
java.nio.file.NoSuchFileException in DebugLogStore.finalizeRun()
FileUtils.zipDir()Files.walk().

Root cause: DebugLogStore.removeOldLogs() runs at startup over the shared
~/Library/Logs/maestro/ directory and deleted every entry beyond the 6 newest —
including the live working directory of another concurrently-running maestro
process
(a separate invocation, or CLI + Studio). The owning process then tried
to zip its now-deleted directory and crashed. Long runs are most exposed, since
they drop out of the keep-window while still active.

Changes:

  • Race-safe retention (DebugLogStore): replaced count-based pruning with
    pruneLogs() — keep the newest N .zip archives (completed runs) and reap
    working directories only when older than 24h (orphans from crashed runs).
    A live run's freshly-modified directory is never deleted, removing the race at
    its source. Crashed-run leftovers are still reclaimed.
  • Guard FileUtils.zipDir: return early with a warning when the source
    directory does not exist, closing the check-then-walk window.
  • Best-effort finalizeRun: wrap archival in try/catch that warns and
    continues — debug-log cleanup can never crash a completed run.
  • Replaced a silent printStackTrace() in zipDir with a proper warning.

This is a bug fix (Type A); the one extracted helper (pruneLogs) exists to make
the retention policy unit-testable and is not a broader refactor.

Testing

Unit tests added and run via ./gradlew :maestro-client:test (all green):

  • FileUtilsTest: zipDir on a missing source no longer throws and leaves no
    output file (this test reproduces the original crash as a red test); happy-path
    zip/unzip still works.
  • DebugLogStoreTest: pruneLogs keeps the newest archives, deletes a stale
    orphan working dir while leaving a fresh (live) dir untouched, and no-ops on a
    missing base directory.

Lint: ./gradlew detekt passes.

Does this need e2e tests? No — this is an internal debug-logging/cleanup
fix with no change to user-facing flow behavior, so it's covered by unit tests.

Issues fixed

Fixes #1522

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[v1.33.1] Exception in thread "main" java.nio.file.NoSuchFileException - Debug output

1 participant